package com.louis.web.paging;

import com.louis.exception.PageException;

public abstract class AbstractPaging<T> implements Paging<T> {

	private static final long	serialVersionUID	= -5415159193332435965L;

	private int					pageSize;
	private int					currentPage;
	private int					totalPage			= -1;

	public AbstractPaging(int pageSize, int currentPage) {
		super();
		setPageSize(pageSize);
		setCurrentPage(currentPage);
	}

	public int getPageSize() {
		return pageSize;
	}

	public final int getFirstResult() {
		int localFirstResult = getPageSize() * (getCurrentPage() - 1);
		return localFirstResult < 0 ?0: localFirstResult;
	}

	public final int getNextPage() {
		return checkCurrentPage(currentPage + 1);
	}

	public final int getPreviousPage() {
		return checkCurrentPage(currentPage - 1);
	}

	public void setPageSize(int pageSize) {
		if (pageSize <= 0) {
			throw new PageException("PageSize can not be less than or equal 0");
		}
		this.pageSize = pageSize;
	}

	public int getCurrentPage() {
		return checkCurrentPage(currentPage);
	}

	public void setCurrentPage(int currentPage) {
		if (currentPage <= 0) {
			throw new PageException("CurrentPage can not be less than or equal 0");
		}
		this.currentPage = currentPage;
	}

	/**
	 * 
	 * @see com.louis.web.paging.Paging#getTotalPage()
	 */
	public final int getTotalPage() {
		if (totalPage < 0) {
			int itemsSize = getItemsSize();
			totalPage = itemsSize / pageSize;
			if (itemsSize % pageSize != 0) {
				totalPage++;
			}
		}
		return totalPage;
	}

	private int checkCurrentPage(int currentPage) {
		if (currentPage < 1) {
			currentPage = 1;
		}
		if (currentPage > getTotalPage()) {
			currentPage = getTotalPage();
		}
		return currentPage;
	}

	/**
	 * @see com.louis.web.paging.Paging#hasNextPage()
	 */
	@Override
	public boolean hasNextPage() {
		return getCurrentPage() < getTotalPage();
	}

	/**
	 * @see com.louis.web.paging.Paging#hasPreviousPage()
	 */
	@Override
	public boolean hasPreviousPage() {
		return getCurrentPage() > 1;
	}

}
